unit DropRest;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Db, FMTBcd, SqlExpr;

type
  TDrop = class(TDataModule)
    Q: TSQLDataSet;
  private
    { Private declarations }
  public
    { Public declarations }
    procedure Run(Meta : String; Typ : Integer; DropSelf : Boolean);
    function HasDependencies(Meta : String) : Boolean;
  end;

var
  Drop: TDrop;

implementation

uses Data, ReportForm;

{$R *.DFM}

{ TDrop }

function TDrop.HasDependencies(Meta: String): Boolean;
begin
  Q.ParamByName('Meta').AsString:=Meta;
  Q.Open;
  Result:=Q.RecordCount>0;
  Q.Close;
end;

procedure TDrop.Run(Meta: String; Typ : Integer; DropSelf : Boolean);
var Q1 : TSQLDataSet;
    S1 : String;

    function GetSQLForComputedField : String;
    var Q2 : TSQLDataSet;
        S2 : String;
    begin
      Q2:=DM.CreateQueryOldDB;
      S2:='select rdb$relation_name, rdb$field_name from RDB$RELATION_FIELDS '+
          'where RDB$FIELD_SOURCE='#39+Meta+#39;
      Q2.CommandText:=S2;
      Q2.Open;
      Result:='alter table '+Q2.FieldByName('rdb$relation_name').AsString+
        'drop '+Q2.FieldByName('rdb$field_name').AsString;
    end;

begin
  // before I could drop element I need to check dependencies
  Q1:=DM.CreateQueryOldDB;
  S1:='select * from RDB$DEPENDENCIES'+
      ' where RDB$DEPENDED_ON_NAME='#39+Meta+#39+
      ' and RDB$FIELD_NAME is null';
  Q1.CommandText:=S1;
  Q1.Open;
  While not Q1.Eof do
  begin
    // is there a recursion ?
    if Trim(Q1.FieldByName('RDB$DEPENDENT_NAME').AsString)<>Trim(Meta) then
      Run(Trim(Q1.FieldByName('RDB$DEPENDENT_NAME').AsString),Q1.FieldByName('RDB$DEPENDENT_TYPE').AsInteger,True);
    Q1.Next;
  end;
  Q1.Close;

  // and finally drop object
  if DropSelf then
  begin
    DM.SQL.Clear;
    case Typ of
      0 : DM.SQL.Add('drop table '+Meta);
      2 : DM.SQL.Add('drop trigger '+Meta);
      3 : // computed field
          DM.SQL.Add(GetSQLForComputedField);
      5 : DM.SQL.Add('drop procedure '+Meta);
      15: DM.SQL.Add('drop external function '+Meta);
    end;

    if DM.AutoRepair then
    begin
      try
        DM.ExecRunSQL;
        if DM.ShowReport then Rep.AddToReport('Dependend',Meta,'dropped');
      except
        if DM.ShowReport then Rep.AddToReport('Dependend',Meta,'error');
      end;
    end else
    begin
      DM.AddToStrings('Dependend '+Meta, DM.SQL);
      if DM.ShowReport then Rep.AddToReport('Dependend',Meta,'dropped');
    end;
  end;
end;

end.
